package controller.parameterpanels;

import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;

import model.IManufacturingMethod;
import model.auxillary.DuplicateNameException;
import model.scaling.ICompany;
import model.scaling.IEBenchmarkScaling;
import model.scaling.IFacility;
import model.scaling.IFactory;
import model.scaling.IIndustrialSector;
import model.scaling.ILocation;
import model.scaling.IProduct;
import view.AlphaTextField;

/**
 * The {@code ListenerAlphaTextField} class controls the user written
 * content of an {@code AlphaTextField} that changes the name of geometry sets,
 * facilities, factories, locations, companies, industrial sectors and products.
 * @author Oliver Eckstein & Sebastian Perlwitz
 *
 */
public class ListenerAlphaTextField implements DocumentListener,
		FocusListener {
	
	/**
	 * The text field to be controlled.
	 */
	private AlphaTextField textField;
	
	/**
	 * The controller of the parameter panel that shows the
	 * {@code AlphaTextField}.
	 */
	private CtrInputParameterPanel controller;
	
	/**
	 * The controller of the parameter panel that shows the
	 * {@code AlphaTextField}.
	 */
	private CtrFacilityPanel controllerFacilityPanel; //#Neu
	
	/**
	 * The controller of the parameter panel that shows the
	 * {@code AlphaTextField}.
	 */
	private CtrFactoryPanel controllerFactoryPanel; //#Neu
	
	/**
	 * The controller of the parameter panel that shows the
	 * {@code AlphaTextField}.
	 */
	private CtrLocationPanel controllerLocationPanel; //#Neu
	
	/**
	 * The controller of the parameter panel that shows the
	 * {@code AlphaTextField}.
	 */
	private CtrCompanyPanel controllerCompanyPanel; //#Neu
	
	/**
	 * The controller of the parameter panel that shows the
	 * {@code AlphaTextField}.
	 */
	private CtrIndustrialSectorPanel controllerIndustryPanel; //#Neu
	
	/**
	 * The controller of the parameter panel that shows the
	 * {@code AlphaTextField}.
	 */
	private CtrProductPanel controllerProductPanel; //#Neu
	
	/**
	 * The model that holds the geometry set.
	 */
	private IManufacturingMethod manuMethod;
	
	/**
	 * The model that holds the facility.
	 */
	private IFacility facility; //#Neu
	
	/**
	 * The model that holds the factory.
	 */
	private IFactory factory; //#Neu
	
	/**
	 * The model that holds the location.
	 */
	private ILocation location; //#Neu
	
	/**
	 * The model that holds the company.
	 */
	private ICompany company; //#Neu
	
	/**
	 * The model that holds the industrial sector.
	 */
	private IIndustrialSector industry; //#Neu
	
	/**
	 * The model that holds the product.
	 */
	private IProduct product; //#Neu
	
	/**
	 * The model that holds all scaling levels.
	 */
	private IEBenchmarkScaling eBenchmarkScaling; //#Neu
	
	/**
	 * The ID of the part process/geometry set that gets controlled.
	 */
	private String partProcessId;
	
	/**
	 * To create a new {@code ListenerAlphaTextField}.
	 * @param textField the text field that gets controlled.
	 * @param controller the controller of the view where the text field is
	 * located.
	 * @param manuMethod the model that holds the geometry set.
	 * @param partProcessId the ID of the part process that gets controlled.
	 */
	public ListenerAlphaTextField(
			AlphaTextField textField,
			CtrInputParameterPanel controller,
			IManufacturingMethod manuMethod,
			String partProcessId) {
		this.textField = textField;
		this.controller = controller;
		this.manuMethod = manuMethod;
		this.partProcessId = partProcessId;
		textField.addFocusListener(this);
	}
	
	//#Neu
	/**
	 * To create a new {@code ListenerAlphaTextField}.
	 * @param textField the text field that gets controlled.
	 * @param controller the controller of the view where the text field is
	 * located.
	 * @param facility the model that holds the name.
	 * @param eBenchmarkScaling the model that holds all facilities.
	 */
	public ListenerAlphaTextField(
			AlphaTextField textField,
			CtrFacilityPanel controller,
			IFacility facility,
			IEBenchmarkScaling eBenchmarkScaling) {
		this.textField = textField;
		this.controllerFacilityPanel = controller;
		this.facility = facility;
		this.eBenchmarkScaling = eBenchmarkScaling;
		textField.addFocusListener(this);
	}
	
	//#Neu
	/**
	 * To create a new {@code ListenerAlphaTextField}.
	 * @param textField the text field that gets controlled.
	 * @param controller the controller of the view where the text field is
	 * located.
	 * @param factory the model that holds the name.
	 * @param eBenchmarkScaling the model that holds all factories.
	 */
	public ListenerAlphaTextField(
			AlphaTextField textField,
			CtrFactoryPanel controller,
			IFactory factory,
			IEBenchmarkScaling eBenchmarkScaling) {
		this.textField = textField;
		this.controllerFactoryPanel = controller;
		this.factory = factory;
		this.eBenchmarkScaling = eBenchmarkScaling;
		textField.addFocusListener(this);
	}
	
	//#Neu
	/**
	 * To create a new {@code ListenerAlphaTextField}.
	 * @param textField the text field that gets controlled.
	 * @param controller the controller of the view where the text field is
	 * located.
	 * @param location the model that holds the name.
	 * @param eBenchmarkScaling the model that holds all locations.
	 */
	public ListenerAlphaTextField(
			AlphaTextField textField,
			CtrLocationPanel controller,
			ILocation location,
			IEBenchmarkScaling eBenchmarkScaling) {
		this.textField = textField;
		this.controllerLocationPanel = controller;
		this.location = location;
		this.eBenchmarkScaling = eBenchmarkScaling;
		textField.addFocusListener(this);
	}
	
	//#Neu
	/**
	 * To create a new {@code ListenerAlphaTextField}.
	 * @param textField the text field that gets controlled.
	 * @param controller the controller of the view where the text field is
	 * located.
	 * @param company the model that holds the name.
	 * @param eBenchmarkScaling the model that holds all companies.
	 */
	public ListenerAlphaTextField(
			AlphaTextField textField,
			CtrCompanyPanel controller,
			ICompany company,
			IEBenchmarkScaling eBenchmarkScaling) {
		this.textField = textField;
		this.controllerCompanyPanel = controller;
		this.company = company;
		this.eBenchmarkScaling = eBenchmarkScaling;
		textField.addFocusListener(this);
	}
	
	//#Neu
	/**
	 * To create a new {@code ListenerAlphaTextField}.
	 * @param textField the text field that gets controlled.
	 * @param controller the controller of the view where the text field is
	 * located.
	 * @param industry the model that holds the name.
	 * @param eBenchmarkScaling the model that holds all industrial sectors.
	 */
	public ListenerAlphaTextField(
			AlphaTextField textField,
			CtrIndustrialSectorPanel controller,
			IIndustrialSector industry,
			IEBenchmarkScaling eBenchmarkScaling) {
		this.textField = textField;
		this.controllerIndustryPanel = controller;
		this.industry = industry;
		this.eBenchmarkScaling = eBenchmarkScaling;
		textField.addFocusListener(this);
	}
	
	//#Neu
	/**
	 * To create a new {@code ListenerAlphaTextField}.
	 * @param textField the text field that gets controlled.
	 * @param controller the controller of the view where the text field is
	 * located.
	 * @param industry the model that holds the name.
	 * @param eBenchmarkScaling the model that holds all products.
	 */
	public ListenerAlphaTextField(
			AlphaTextField textField,
			CtrProductPanel controller,
			IProduct product,
			IEBenchmarkScaling eBenchmarkScaling) {
		this.textField = textField;
		this.controllerProductPanel = controller;
		this.product = product;
		this.eBenchmarkScaling = eBenchmarkScaling;
		textField.addFocusListener(this);
	}
	
	@Override
	public void focusGained(FocusEvent arg0) {
		textField.selectAll();
	}

	@Override
	public void focusLost(FocusEvent arg0) {
		
		//#Neu
		if(controller != null) {
			// Change the border text.
			textField.setCaretPosition(0);
			String newGeometryDescription = textField.getText();
			CtrGeometryPanel geometryPanelController = 
					(CtrGeometryPanel) controller;
			geometryPanelController.changeBorderText(
					textField, newGeometryDescription);
		} else if(controllerFacilityPanel !=null) {
			// Change the border text.
			textField.setCaretPosition(0);
			String newFacilityDescription = textField.getText();
			CtrFacilityPanel facilityPanelController = 
					controllerFacilityPanel;
			facilityPanelController.changeBorderText(
					textField, newFacilityDescription);
		} else if(controllerFactoryPanel != null) {
			// Change the border text.
			textField.setCaretPosition(0);
			String newFactoryDescription = textField.getText();
			CtrFactoryPanel factoryPanelController = 
					controllerFactoryPanel;
			factoryPanelController.changeBorderText(
					textField, newFactoryDescription);
		} else if(controllerLocationPanel != null) {
			// Change the border text.
			textField.setCaretPosition(0);
			String newLocationDescription = textField.getText();
			CtrLocationPanel locationPanelController = 
					controllerLocationPanel;
			locationPanelController.changeBorderText(
					textField, newLocationDescription);
		} else if(controllerCompanyPanel != null) {
			// Change the border text.
			textField.setCaretPosition(0);
			String newCompanyDescription = textField.getText();
			CtrCompanyPanel companyPanelController = 
					controllerCompanyPanel;
			companyPanelController.changeBorderText(
					textField, newCompanyDescription);
		} else if(controllerIndustryPanel != null) {
			// Change the border text.
			textField.setCaretPosition(0);
			String newIndustryDescription = textField.getText();
			CtrIndustrialSectorPanel industryPanelController = 
					controllerIndustryPanel;
			industryPanelController.changeBorderText(
					textField, newIndustryDescription);
		} else if(controllerProductPanel != null) {
			// Change the border text.
			textField.setCaretPosition(0);
			String newProductDescription = textField.getText();
			CtrProductPanel productPanelController = 
					controllerProductPanel;
			productPanelController.changeBorderText(
					textField, newProductDescription);
		}
	}

	@Override
	public void changedUpdate(DocumentEvent arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void insertUpdate(DocumentEvent arg0) {
		updateValue(arg0);				
	}

	@Override
	public void removeUpdate(DocumentEvent arg0) {
		updateValue(arg0);				
	}

	/**
	 * To change the name of the part process, facility, factory, location,
	 * company, industrial sector or product.
	 * @param e the {@code DocumentEvent}.
	 */
	private void updateValue(DocumentEvent e) {		
		String txt = "";
		try {
            txt = e.getDocument().getText(0, e.getDocument().getLength());
        } catch (BadLocationException e1) {            
            e1.printStackTrace();
        }
		
		if(manuMethod != null) {
			if(txt.equals("")) {
				return;
			}
			manuMethod.getPartProcess(partProcessId).setName(txt);
		} else if(facility != null) { //#Neu
			try {
				eBenchmarkScaling.setFacilityName(facility, txt);
				if(textField.getErrorStatus()) {
					textField.clearError();
					controllerFacilityPanel.removeInvalidInput();
				}
			} catch(IllegalArgumentException|DuplicateNameException exc) {
				textField.showError();
				controllerFacilityPanel.addInvalidInput();
			}
		} else if(factory != null) { //#Neu
			try {
				eBenchmarkScaling.setFactoryName(factory, txt);
				if(textField.getErrorStatus()) {
					textField.clearError();
					controllerFactoryPanel.removeInvalidInput();
				}
			} catch(IllegalArgumentException|DuplicateNameException exc) {
				textField.showError();
				controllerFactoryPanel.addInvalidInput();
			}
		} else if(location != null) { //#Neu
			try {
				eBenchmarkScaling.setLocationName(location, txt);
				if(textField.getErrorStatus()) {
					textField.clearError();
					controllerLocationPanel.removeInvalidInput();
				}
			} catch(IllegalArgumentException|DuplicateNameException exc) {
				textField.showError();
				controllerLocationPanel.addInvalidInput();
			}
		} else if(company != null) { //#Neu
			try {
				eBenchmarkScaling.setCompanyName(company, txt);
				if(textField.getErrorStatus()) {
					textField.clearError();
					controllerCompanyPanel.removeInvalidInput();
				}
			} catch(IllegalArgumentException|DuplicateNameException exc) {
				textField.showError();
				controllerCompanyPanel.addInvalidInput();
			}
		} else if(industry != null) { //#Neu
			try {
				eBenchmarkScaling.setIndustrialSectorName(industry, txt);
				if(textField.getErrorStatus()) {
					textField.clearError();
					controllerIndustryPanel.removeInvalidInput();
				}
			} catch(IllegalArgumentException|DuplicateNameException exc) {
				textField.showError();
				controllerIndustryPanel.addInvalidInput();
			}
		} else if(product != null) { //#Neu
			try {
				eBenchmarkScaling.setProductName(product, txt);
				if(textField.getErrorStatus()) {
					textField.clearError();
					controllerProductPanel.removeInvalidInput();
				}
			} catch(IllegalArgumentException|DuplicateNameException exc) {
				textField.showError();
				controllerProductPanel.addInvalidInput();
			}
		}
	}

}
